import { Request, Response } from 'express';
import Stripe from 'stripe';
import { stripe, stripeConfig } from '../config/stripe';

/**
 * Handle Stripe webhook events
 * POST /api/webhooks/stripe
 */
export const handleStripeWebhook = async (req: Request, res: Response) => {
  const sig = req.headers['stripe-signature'];

  if (!sig) {
    return res.status(400).json({ error: 'Missing stripe-signature header' });
  }

  if (!stripeConfig.webhookSecret) {
    console.error('STRIPE_WEBHOOK_SECRET is not configured');
    return res.status(500).json({ error: 'Webhook secret not configured' });
  }

  let event: Stripe.Event;

  try {
    // Verify webhook signature
    event = stripe.webhooks.constructEvent(
      req.body,
      sig,
      stripeConfig.webhookSecret
    );
  } catch (err: any) {
    console.error('Webhook signature verification failed:', err.message);
    return res.status(400).json({ error: `Webhook Error: ${err.message}` });
  }

  // Handle the event
  try {
    switch (event.type) {
      case 'payment_intent.succeeded':
        await handlePaymentIntentSucceeded(event.data.object as Stripe.PaymentIntent);
        break;

      case 'payment_intent.payment_failed':
        await handlePaymentIntentFailed(event.data.object as Stripe.PaymentIntent);
        break;

      case 'setup_intent.succeeded':
        await handleSetupIntentSucceeded(event.data.object as Stripe.SetupIntent);
        break;

      case 'setup_intent.setup_failed':
        await handleSetupIntentFailed(event.data.object as Stripe.SetupIntent);
        break;

      case 'customer.subscription.created':
      case 'customer.subscription.updated':
      case 'customer.subscription.deleted':
        await handleSubscriptionEvent(event);
        break;

      case 'charge.refunded':
        await handleChargeRefunded(event.data.object as Stripe.Charge);
        break;

      default:
        console.log(`Unhandled event type: ${event.type}`);
    }

    res.json({ received: true });
  } catch (error) {
    console.error('Error handling webhook event:', error);
    res.status(500).json({ error: 'Webhook handler failed' });
  }
};

/**
 * Handle successful payment intent
 */
const handlePaymentIntentSucceeded = async (paymentIntent: Stripe.PaymentIntent) => {
  console.log('💰 Payment succeeded:', {
    id: paymentIntent.id,
    amount: paymentIntent.amount / 100,
    currency: paymentIntent.currency,
    customer: paymentIntent.customer,
    metadata: paymentIntent.metadata,
  });

  // TODO: Implement your business logic
  // - Update user balance in database
  // - Send confirmation email
  // - Record transaction history
  // - Trigger any post-payment workflows

  // Example: Update user balance
  // const userId = paymentIntent.metadata?.userId;
  // const amount = paymentIntent.amount / 100;
  // await updateUserBalance(userId, amount);
};

/**
 * Handle failed payment intent
 */
const handlePaymentIntentFailed = async (paymentIntent: Stripe.PaymentIntent) => {
  console.error('❌ Payment failed:', {
    id: paymentIntent.id,
    amount: paymentIntent.amount / 100,
    currency: paymentIntent.currency,
    customer: paymentIntent.customer,
    last_payment_error: paymentIntent.last_payment_error,
  });

  // TODO: Implement your business logic
  // - Notify user of failed payment
  // - Log the failure
  // - Send alert to admin if needed
};

/**
 * Handle successful setup intent
 */
const handleSetupIntentSucceeded = async (setupIntent: Stripe.SetupIntent) => {
  console.log('💳 Payment method saved:', {
    id: setupIntent.id,
    customer: setupIntent.customer,
    payment_method: setupIntent.payment_method,
    metadata: setupIntent.metadata,
  });

  // TODO: Implement your business logic
  // - Update user's saved payment methods in database
  // - Send confirmation to user
  // - Set as default if specified in metadata
};

/**
 * Handle failed setup intent
 */
const handleSetupIntentFailed = async (setupIntent: Stripe.SetupIntent) => {
  console.error('❌ Setup intent failed:', {
    id: setupIntent.id,
    customer: setupIntent.customer,
    last_setup_error: setupIntent.last_setup_error,
  });

  // TODO: Implement your business logic
  // - Notify user of failure
  // - Log the error
};

/**
 * Handle subscription events
 */
const handleSubscriptionEvent = async (event: Stripe.Event) => {
  const subscription = event.data.object as Stripe.Subscription;
  
  console.log(`📅 Subscription ${event.type}:`, {
    id: subscription.id,
    customer: subscription.customer,
    status: subscription.status,
    current_period_end: new Date(subscription.current_period_end * 1000),
  });

  // TODO: Implement your business logic
  // - Update subscription status in database
  // - Grant/revoke access to features
  // - Send notifications
};

/**
 * Handle charge refunded
 */
const handleChargeRefunded = async (charge: Stripe.Charge) => {
  console.log('💸 Charge refunded:', {
    id: charge.id,
    amount: charge.amount / 100,
    amount_refunded: charge.amount_refunded / 100,
    refunded: charge.refunded,
  });

  // TODO: Implement your business logic
  // - Update user balance
  // - Send refund confirmation email
  // - Log refund in transaction history
};
